/**
 * \file serializer.cpp
 * \brief Serializer class implementation
 * \author Marc Laval
 * \version 0.1
 * \date 10/2011
 *
 */

#include "serializer.h"

//----------------------------------------------------------------------
/*! \brief Standard constructor
 *  \param buf CommandBuffer
 */
Serializer::Serializer(ByteBuffer * buf)
{
	m_buf = buf;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data unsigned 8bit int
 */
bool Serializer::serialize(uint8 data)
{
	if(m_buf == NULL)
		return false;

	m_buf->push_back(data);

	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data unsigned 16bit int
 */
bool Serializer::serialize(uint16 data)
{
	if(m_buf == NULL)
		return false;

	m_buf->push_back(data & 0xFF);
	m_buf->push_back((data >> 8) & 0xFF);

	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data unsigned 32bit int
 */
bool Serializer::serialize(uint32 data)
{
	if(m_buf == NULL)
		return false;

	m_buf->push_back(data & 0xFF);
	m_buf->push_back((data >> 8) & 0xFF);
	m_buf->push_back((data >> 16) & 0xFF);
	m_buf->push_back((data >> 24) & 0xFF);

	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data unsigned 64bit int
 */
bool Serializer::serialize(uint64 data)
{
	if(m_buf == NULL)
		return false;

	m_buf->push_back(data & 0xFF);
	m_buf->push_back((data >> 8) & 0xFF);
	m_buf->push_back((data >> 16) & 0xFF);
	m_buf->push_back((data >> 24) & 0xFF);
	m_buf->push_back((data >> 32) & 0xFF);
	m_buf->push_back((data >> 40) & 0xFF);
	m_buf->push_back((data >> 48) & 0xFF);
	m_buf->push_back((data >> 56) & 0xFF);

	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data boolean
 */
bool Serializer::serialize(bool data)
{
	if(m_buf == NULL)
		return false;

	byte tmp;
	if(data) tmp = 1; else tmp = 0;

	m_buf->push_back(tmp);
	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data float
 */
bool Serializer::serialize(float data)
{
	if(m_buf == NULL)
		return false;

	//Get float falue as an int without casting it
	uint32 val = *((uint32*) &data);

	m_buf->push_back(val & 0xFF);
	m_buf->push_back((val >> 8) & 0xFF);
	m_buf->push_back((val >> 16) & 0xFF);
	m_buf->push_back((val >> 24) & 0xFF);
	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data double
 */
bool Serializer::serialize(double data)
{
	if(m_buf == NULL)
		return false;

	//We get float falue as an int without casting it
	uint64 val = *(uint64*) &data;

	m_buf->push_back(val & 0xFF);
	m_buf->push_back((val >> 8) & 0xFF);
	m_buf->push_back((val >> 16) & 0xFF);
	m_buf->push_back((val >> 24) & 0xFF);
	m_buf->push_back((val >> 32) & 0xFF);
	m_buf->push_back((val >> 40) & 0xFF);
	m_buf->push_back((val >> 48) & 0xFF);
	m_buf->push_back((val >> 56) & 0xFF);
	return true;
}

//----------------------------------------------------------------------
/*! \brief Serializes data and add it to the buffer
 *  \param data string
 */
bool Serializer::serialize(string data)
{
	if(m_buf == NULL)
		return false;

	for(uint32 i=0; i<data.size(); i++)
	{
		m_buf->push_back(data[i]);
	}

	m_buf->push_back(NULL_CHAR);

	return true;
}
